#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
业务逻辑处理器
将业务逻辑从GUI中分离，提高代码的可测试性和可维护性
"""

import os
import shutil
from .scrapers import ListGenerator, MovieScraper
from .config import LIST_FILE_NAME, LOST_FILE_NAME
from .utils import FileUtils, ValidationUtils


class MovieProcessor:
    """电影处理业务逻辑"""
    
    def __init__(self, log_callback=None):
        self.log_callback = log_callback
    
    def _log(self, message):
        """记录日志"""
        if self.log_callback:
            self.log_callback(message)
        else:
            print(message)
    
    def organize_movies(self, folder_path):
        """整理电影文件"""
        try:
            # 验证文件夹路径
            valid, error_msg = ValidationUtils.validate_folder_path(folder_path)
            if not valid:
                raise ValueError(error_msg)
            
            self._log(f"📁 开始整理电影文件: {folder_path}")
            
            # 获取所有电影文件
            movie_files = []
            for file in os.listdir(folder_path):
                file_path = os.path.join(folder_path, file)
                if os.path.isfile(file_path) and FileUtils.is_video_file(file_path):
                    movie_files.append(file)
            
            if not movie_files:
                self._log("⚠️ 未找到视频文件")
                return
            
            self._log(f"🎬 找到 {len(movie_files)} 个视频文件")
            
            organized_count = 0
            for movie_file in movie_files:
                try:
                    # 获取文件名（不含扩展名）
                    file_name, _ = os.path.splitext(movie_file)
                    
                    # 按'.'分割，取第一部分作为文件夹名
                    folder_name = file_name.split('.')[0].strip()
                    
                    if not folder_name:
                        self._log(f"⚠️ 跳过无效文件名: {movie_file}")
                        continue
                    
                    # 创建电影文件夹
                    movie_folder_path = os.path.join(folder_path, folder_name)
                    FileUtils.ensure_directory_exists(movie_folder_path)
                    
                    # 移动文件到文件夹
                    source_path = os.path.join(folder_path, movie_file)
                    target_path = os.path.join(movie_folder_path, movie_file)
                    
                    if not os.path.exists(target_path):
                        shutil.move(source_path, target_path)
                        self._log(f"✅ 已整理: {folder_name}/{movie_file}")
                        organized_count += 1
                    else:
                        self._log(f"⚠️ 文件已存在，跳过: {folder_name}/{movie_file}")
                
                except Exception as e:
                    self._log(f"❌ 整理失败: {movie_file} - {e}")
            
            self._log(f"🎉 整理完成！共整理 {organized_count} 个文件")
            
        except Exception as e:
            self._log(f"❌ 整理过程出错: {e}")
            raise
    
    def collect_movie_links(self, folder_path, delete_existing=False):
        """收集电影链接"""
        try:
            # 验证文件夹路径
            valid, error_msg = ValidationUtils.validate_folder_path(folder_path)
            if not valid:
                raise ValueError(error_msg)
            
            self._log(f"🔍 开始收集电影链接: {folder_path}")
            
            # 创建ListGenerator实例
            generator = ListGenerator(gui_callback=self.log_callback)
            
            # 处理删除原有文件的选项
            list_file_path = os.path.join(folder_path, LIST_FILE_NAME)
            if delete_existing and os.path.exists(list_file_path):
                try:
                    os.remove(list_file_path)
                    self._log(f"🗑️ 已删除原有 {LIST_FILE_NAME} 文件")
                except Exception as e:
                    self._log(f"⚠️ 删除 {LIST_FILE_NAME} 失败: {e}")
            
            # 生成电影链接列表
            generator.generate_list(folder_path)
            self._log("🎉 电影链接收集完成!")
            
        except Exception as e:
            self._log(f"❌ 收集链接过程出错: {e}")
            raise
    
    def generate_nfo_files(self, folder_path, options, progress_callback=None):
        """生成NFO文件"""
        try:
            # 验证文件夹路径
            valid, error_msg = ValidationUtils.validate_folder_path(folder_path)
            if not valid:
                raise ValueError(error_msg)
            
            # 检查电影列表文件是否存在
            list_file_path = os.path.join(folder_path, LIST_FILE_NAME)
            if not os.path.exists(list_file_path):
                raise FileNotFoundError(f"未找到 {LIST_FILE_NAME} 文件，请先执行步骤2")
            
            self._log(f"📄 开始生成NFO文件: {folder_path}")
            
            # 创建MovieScraper实例
            scraper = MovieScraper(gui_callback=self.log_callback)
            
            # 设置选项
            scraper.download_images = options.get('download_images', True)
            allow_overwrite = options.get('allow_overwrite', False)
            
            if scraper.download_images:
                self._log("🖼️ 已启用海报与同人画下载")
            else:
                self._log("ℹ️ 已禁用海报与同人画下载")
            
            if allow_overwrite:
                self._log("⚠️ 已启用覆盖模式，将覆盖已存在的NFO文件")
            else:
                self._log("ℹ️ 跳过模式：将跳过已存在的NFO文件")
            
            # 读取电影列表文件
            with open(list_file_path, 'r', encoding='utf-8') as f:
                list_content = f.read()
            
            movie_lines = [line.strip() for line in list_content.split('\n') if line.strip()]
            self._log(f"📋 找到 {len(movie_lines)} 部电影待处理")
            
            success_count = 0
            failed_count = 0
            skipped_count = 0
            
            for i, line in enumerate(movie_lines):
                try:
                    # 解析电影信息
                    if '||' not in line:
                        self._log(f"⚠️ 跳过格式错误的行: {line}")
                        failed_count += 1
                        continue

                    parts = line.split('||', 1)  # 只分割第一个||，防止URL中包含||
                    if len(parts) != 2:
                        self._log(f"⚠️ 跳过格式错误的行: {line}")
                        failed_count += 1
                        continue

                    movie_name = parts[0].strip()
                    movie_url = parts[1].strip()

                    self._log(f"\n📂 处理电影 ({i+1}/{len(movie_lines)}): {movie_name}")

                    # 查找电影文件夹
                    movie_folder_path = os.path.join(folder_path, movie_name)
                    if not os.path.exists(movie_folder_path):
                        self._log(f"❌ 未找到电影文件夹: {movie_name}")
                        failed_count += 1
                        continue

                    # 获取视频文件名
                    video_file_name = FileUtils.get_largest_video_file(movie_folder_path)
                    nfo_file_path = os.path.join(movie_folder_path, f"{video_file_name}.nfo")

                    # 检查是否需要处理NFO文件
                    should_process_nfo = allow_overwrite or not os.path.exists(nfo_file_path)

                    if should_process_nfo:
                        # 爬取电影信息到指定文件夹
                        scraper.scrape_movie_info_to_folder(movie_url, movie_folder_path, movie_name)
                        success_count += 1
                    else:
                        # NFO文件已存在，但仍需检查并下载海报
                        if scraper.download_images:
                            self._log(f"🖼️ 检查海报文件: {movie_name}")
                            scraper.download_images_from_url(movie_url, movie_folder_path, movie_name, video_file_name)
                        success_count += 1

                    # 自动进度递增，优先调用 progress_callback
                    percent = int((i + 1) / len(movie_lines) * 100)
                    message = f"正在处理 {movie_name} ({i+1}/{len(movie_lines)})"
                    if progress_callback:
                        progress_callback(percent, message)
                    elif hasattr(self, 'grouped_controls') and self.grouped_controls:
                        self.grouped_controls.set_progress('generate_nfo', percent, message)

                    # 添加延迟，避免请求过于频繁
                    if i < len(movie_lines) - 1:
                        scraper.add_delay(2)

                except Exception as error:
                    self._log(f"❌ 处理失败: {movie_name} - {error}")
                    failed_count += 1
            
        except Exception as e:
            self._log(f"❌ 生成NFO文件过程出错: {e}")
            raise
    
    def download_posters_from_nfo(self, folder_path, progress_callback=None):
        """根据NFO文件下载海报"""
        try:
            # 验证文件夹路径
            valid, error_msg = ValidationUtils.validate_folder_path(folder_path)
            if not valid:
                raise ValueError(error_msg)

            self._log(f"🖼️ 开始根据NFO文件下载海报: {folder_path}")

            # 创建MovieScraper实例
            scraper = MovieScraper(gui_callback=self.log_callback)

            # 调用scrapers.py中的方法，传递进度回调
            success_count, failed_count, skipped_count = scraper.process_nfo_poster_download(
                folder_path, FileUtils.get_largest_video_file, progress_callback
            )

            return success_count, failed_count, skipped_count

        except Exception as e:
            self._log(f"❌ 下载海报过程出错: {e}")
            raise


class ListManager:
    """电影列表管理业务逻辑"""
    
    def __init__(self, log_callback=None):
        self.log_callback = log_callback
    
    def _log(self, message):
        """记录日志"""
        if self.log_callback:
            self.log_callback(message)
        else:
            print(message)
    
    def load_movie_list(self, folder_path):
        """加载电影列表"""
        try:
            list_file_path = os.path.join(folder_path, LIST_FILE_NAME)
            
            if not os.path.exists(list_file_path):
                self._log(f"⚠️ 未找到 {LIST_FILE_NAME} 文件")
                return []
            
            movies = []
            with open(list_file_path, 'r', encoding='utf-8') as f:
                lines = f.readlines()
            
            for i, line in enumerate(lines, 1):
                line = line.strip()
                if line:
                    if '||' in line:
                        parts = line.split('||', 1)
                        if len(parts) == 2:
                            name, url = parts
                            movies.append((i, name.strip(), url.strip()))
                        else:
                            self._log(f"⚠️ 跳过格式错误的行 {i}: {line}")
                    else:
                        self._log(f"⚠️ 跳过格式错误的行 {i}: {line}")
            
            self._log(f"📋 加载了 {len(movies)} 部电影")
            return movies
            
        except Exception as e:
            self._log(f"❌ 加载 {LIST_FILE_NAME} 失败: {e}")
            return []
    
    def save_movie_list(self, folder_path, movies):
        """保存电影列表"""
        try:
            list_file_path = os.path.join(folder_path, LIST_FILE_NAME)
            
            with open(list_file_path, 'w', encoding='utf-8') as f:
                for _, name, url in movies:
                    f.write(f"{name} - {url}\n")
            
            self._log(f"💾 已保存 {len(movies)} 部电影到 {LIST_FILE_NAME}")
            
        except Exception as e:
            self._log(f"❌ 保存 {LIST_FILE_NAME} 失败: {e}")
            raise
    
    def add_movie(self, folder_path, name, url):
        """添加电影"""
        try:
            # 验证输入
            valid_name, name_error = ValidationUtils.validate_movie_name(name)
            if not valid_name:
                raise ValueError(name_error)
            
            valid_url, url_error = ValidationUtils.validate_url(url)
            if not valid_url:
                raise ValueError(url_error)
            
            # 加载现有列表
            movies = self.load_movie_list(folder_path)
            
            # 检查是否已存在
            for _, existing_name, existing_url in movies:
                if existing_name == name or existing_url == url:
                    raise ValueError("电影名称或URL已存在")
            
            # 添加新电影
            new_index = len(movies) + 1
            movies.append((new_index, name, url))
            
            # 保存列表
            self.save_movie_list(folder_path, movies)
            
            self._log(f"✅ 已添加电影: {name}")
            return movies
            
        except Exception as e:
            self._log(f"❌ 添加电影失败: {e}")
            raise
    
    def update_movie(self, folder_path, old_name, new_name, new_url):
        """更新电影信息"""
        try:
            # 验证输入
            valid_name, name_error = ValidationUtils.validate_movie_name(new_name)
            if not valid_name:
                raise ValueError(name_error)
            
            valid_url, url_error = ValidationUtils.validate_url(new_url)
            if not valid_url:
                raise ValueError(url_error)
            
            # 加载现有列表
            movies = self.load_movie_list(folder_path)
            
            # 查找并更新
            updated = False
            for i, (index, name, url) in enumerate(movies):
                if name == old_name:
                    movies[i] = (index, new_name, new_url)
                    updated = True
                    break
            
            if not updated:
                raise ValueError(f"未找到电影: {old_name}")
            
            # 保存列表
            self.save_movie_list(folder_path, movies)
            
            self._log(f"✅ 已更新电影: {old_name} -> {new_name}")
            return movies
            
        except Exception as e:
            self._log(f"❌ 更新电影失败: {e}")
            raise
    
    def delete_movie(self, folder_path, name):
        """删除电影"""
        try:
            # 加载现有列表
            movies = self.load_movie_list(folder_path)
            
            # 查找并删除
            movies = [(i+1, n, u) for i, (_, n, u) in enumerate(movies) if n != name]
            
            # 保存列表
            self.save_movie_list(folder_path, movies)
            
            self._log(f"✅ 已删除电影: {name}")
            return movies
            
        except Exception as e:
            self._log(f"❌ 删除电影失败: {e}")
            raise


class MovieWorkflowController:
    """电影工作流控制器 - 统一管理所有主要业务功能"""

    def __init__(self, log_callback=None):
        self.log_callback = log_callback
        self.movie_processor = MovieProcessor(log_callback)
        self.list_manager = ListManager(log_callback)

    def _log(self, message):
        """记录日志"""
        if self.log_callback:
            self.log_callback(message)
        else:
            print(message)

    def collect_movie_links(self, folder_path, options, progress_callback=None, gui_parent=None):
        """收集电影链接的主要业务逻辑"""
        try:
            from .scrapers import ListGenerator

            # 验证文件夹路径
            valid, error_msg = ValidationUtils.validate_folder_path(folder_path)
            if not valid:
                raise ValueError(error_msg)

            self._log(f"🔗 开始收集电影链接: {folder_path}")

            # 阶段1：初始化 (0-10%)
            if progress_callback:
                progress_callback(0, "正在初始化...")

            # 创建ListGenerator实例
            generator = ListGenerator(gui_callback=self.log_callback)
            if gui_parent:
                generator._gui_parent = gui_parent

            # 处理删除原有List.txt选项
            list_file_path = os.path.join(folder_path, LIST_FILE_NAME)
            if options.get('delete_list', False):
                if os.path.exists(list_file_path):
                    try:
                        os.remove(list_file_path)
                        self._log(f"🗑️ 已删除原有 {LIST_FILE_NAME} 文件")
                    except Exception as e:
                        self._log(f"⚠️ 删除 {LIST_FILE_NAME} 失败: {e}")

            # 阶段2：扫描文件夹 (10-20%)
            if progress_callback:
                progress_callback(10, "正在扫描电影文件夹...")

            # 调用核心处理逻辑
            success_count, failed_count = self._process_movie_links_with_progress(
                generator, folder_path, progress_callback
            )

            self._log("🎉 电影链接收集完成!")
            return success_count, failed_count

        except Exception as e:
            self._log(f"❌ 收集电影链接过程出错: {e}")
            raise

    def _process_movie_links_with_progress(self, generator, folder_path, progress_callback=None):
        """带进度更新的电影链接处理逻辑"""
        self._log(f"📁 开始扫描电影文件夹: {folder_path}")

        # 检查文件夹是否存在
        if not os.path.exists(folder_path):
            self._log(f"❌ 错误: 文件夹不存在: {folder_path}")
            return 0, 1

        # 读取已存在的List.txt文件
        processed_movies = generator.read_existing_list(folder_path)
        list_file_path = os.path.join(folder_path, LIST_FILE_NAME)
        lost_file_path = os.path.join(folder_path, LOST_FILE_NAME)

        # 阶段3：读取文件夹列表 (20-30%)
        if progress_callback:
            progress_callback(20, "正在读取电影文件夹...")

        # 读取所有子文件夹
        try:
            items = os.listdir(folder_path)
            movie_folders = [item for item in items if os.path.isdir(os.path.join(folder_path, item))]
        except Exception as error:
            self._log(f"❌ 读取文件夹时出错: {error}")
            return 0, 1

        if not movie_folders:
            self._log("⚠️ 未找到任何子文件夹")
            return 0, 0

        # 过滤出未处理的电影
        unprocessed_movies = [movie for movie in movie_folders if movie not in processed_movies]

        self._log(f"🎬 找到 {len(movie_folders)} 个电影文件夹")
        self._log(f"📋 其中 {len(processed_movies)} 个已处理，{len(unprocessed_movies)} 个待处理")

        if not unprocessed_movies:
            self._log("✅ 所有电影都已处理完成")
            return len(processed_movies), 0

        # 阶段4：处理电影 (30-95%)
        if progress_callback:
            progress_callback(30, f"开始处理 {len(unprocessed_movies)} 部电影...")

        return self._search_and_process_movies(
            generator, unprocessed_movies, folder_path,
            list_file_path, lost_file_path, progress_callback
        )

    def _search_and_process_movies(self, generator, unprocessed_movies, folder_path,
                                   list_file_path, lost_file_path, progress_callback=None):
        """搜索和处理电影"""
        processed_count = 0
        lost_count = 0
        total_movies = len(unprocessed_movies)

        for i, movie_name in enumerate(unprocessed_movies):
            # 更新进度条 (30-95%的范围)
            if progress_callback:
                progress = int(30 + (i / total_movies) * 65)
                current_movie = movie_name[:15] + "..." if len(movie_name) > 15 else movie_name
                progress_callback(progress, f"搜索中: {current_movie} ({i+1}/{total_movies})")

            self._log(f"\n🔍 [{i + 1}/{total_movies}] 搜索电影: {movie_name}")

            try:
                # 搜索电影
                search_results = generator.search_movie(movie_name)

                if not search_results:
                    self._log(f"❌ 未找到搜索结果: {movie_name}")
                    lost_entry = f"未找到搜索结果: {movie_name}"
                    with open(lost_file_path, 'a', encoding='utf-8') as f:
                        f.write(lost_entry + '\n')
                    lost_count += 1
                    continue

                # 处理搜索结果
                result = self._handle_search_results(
                    generator, movie_name, search_results, folder_path,
                    list_file_path, lost_file_path
                )

                if result == 'processed':
                    processed_count += 1
                else:
                    lost_count += 1

                # 添加延迟，避免请求过于频繁
                if i < len(unprocessed_movies) - 1:
                    self._log('⏳ 等待 1 秒...')
                    generator.add_delay(1)

            except Exception as error:
                self._log(f"❌ 处理 {movie_name} 时出错: {error}")
                lost_entry = f"处理出错: {movie_name} - {error}"
                with open(lost_file_path, 'a', encoding='utf-8') as f:
                    f.write(lost_entry + '\n')
                lost_count += 1

        # 阶段5：完成处理 (95-100%)
        if progress_callback:
            progress_callback(95, "正在完成处理...")

        self._log(f"\n🎉 处理完成!")
        self._log(f"   - 成功处理: {processed_count} 部电影 (已写入 List.txt)")
        self._log(f"   - 未处理/跳过: {lost_count} 部电影 (已写入 lost.txt)")
        self._log(f"   请审阅电影目录下的List.txt和lost.txt，方便进行下一步")

        return processed_count, lost_count

    def _handle_search_results(self, generator, movie_name, search_results, folder_path,
                               list_file_path, lost_file_path):
        """处理搜索结果"""
        if len(search_results) == 1:
            # 唯一结果，直接使用
            movie_url = search_results[0]['url']
            self._log(f"✅ 找到唯一匹配: {movie_url}")

            # 写入到List.txt
            with open(list_file_path, 'a', encoding='utf-8') as f:
                f.write(f"{movie_name}||{movie_url}\n")
            return 'processed'

        else:
            # 多个结果，需要用户选择
            self._log(f"🔍 找到 {len(search_results)} 个可能的匹配结果:")
            for j, result in enumerate(search_results, 1):
                self._log(f"   {j}. {result['title']} ({result['year']}) - {result['url']}")

            # 获取用户选择
            movie_folder_path = os.path.join(folder_path, movie_name)
            choice = generator.get_user_choice(movie_name, search_results, movie_folder_path)

            if 1 <= choice <= len(search_results):
                # 用户选择了某个结果
                selected_result = search_results[choice - 1]
                selected_url = selected_result['url']
                year_str = f" ({selected_result['year']})" if selected_result['year'] else ''
                self._log(f"✅ 用户选择: {selected_result['title']}{year_str}")

                # 写入到List.txt
                with open(list_file_path, 'a', encoding='utf-8') as f:
                    f.write(f"{movie_name}||{selected_url}\n")

                # 记录用户选择到lost.txt
                lost_entry = f"用户选择: {movie_name} -> {selected_result['title']}{year_str} ({selected_url})"
                with open(lost_file_path, 'a', encoding='utf-8') as f:
                    f.write(lost_entry + '\n')
                return 'processed'

            else:
                # 用户选择跳过（choice == 0）
                self._log(f"⏭️ 跳过: {movie_name}")

                # 写入到lost.txt
                lost_entry = f"用户跳过: {movie_name}"
                with open(lost_file_path, 'a', encoding='utf-8') as f:
                    f.write(lost_entry + '\n')
                return 'skipped'

    def organize_movie_files(self, folder_path, progress_callback=None):
        """整理电影文件的主要业务逻辑"""
        try:
            # 验证文件夹路径
            valid, error_msg = ValidationUtils.validate_folder_path(folder_path)
            if not valid:
                raise ValueError(error_msg)

            self._log(f"📁 开始整理电影文件: {folder_path}")

            # 阶段1：初始化 (0-10%)
            if progress_callback:
                progress_callback(0, "正在初始化...")

            # 调用核心整理逻辑
            organized_count, skipped_count = self._organize_files_with_progress(
                folder_path, progress_callback
            )

            self._log("🎉 电影文件整理完成!")
            return organized_count, skipped_count

        except Exception as e:
            self._log(f"❌ 整理电影文件过程出错: {e}")
            raise

    def _organize_files_with_progress(self, folder_path, progress_callback=None):
        """带进度更新的文件整理逻辑"""
        # 支持的电影文件格式
        movie_extensions = {'.mp4', '.mkv', '.rmvb', '.avi', '.mov', '.wmv', '.flv'}

        self._log(f"📁 开始扫描文件夹: {folder_path}")

        # 阶段2：扫描文件 (10-20%)
        if progress_callback:
            progress_callback(10, "正在扫描电影文件...")

        # 获取所有电影文件
        movie_files = []
        try:
            for item in os.listdir(folder_path):
                item_path = os.path.join(folder_path, item)
                if os.path.isfile(item_path):
                    _, ext = os.path.splitext(item.lower())
                    if ext in movie_extensions:
                        movie_files.append(item)
        except Exception as error:
            self._log(f"❌ 扫描文件夹时出错: {error}")
            return 0, 0

        if not movie_files:
            self._log("⚠️ 未找到任何电影文件")
            return 0, 0

        self._log(f"🎬 找到 {len(movie_files)} 个电影文件")

        # 阶段3：整理文件 (20-95%)
        if progress_callback:
            progress_callback(20, f"开始整理 {len(movie_files)} 个文件...")

        return self._process_movie_files(movie_files, folder_path, progress_callback)

    def _process_movie_files(self, movie_files, folder_path, progress_callback=None):
        """处理电影文件"""
        organized_count = 0
        skipped_count = 0
        total_files = len(movie_files)

        for i, movie_file in enumerate(movie_files):
            # 更新进度条 (20-95%的范围)
            if progress_callback:
                progress = int(20 + (i / total_files) * 75)
                current_file = movie_file[:20] + "..." if len(movie_file) > 20 else movie_file
                progress_callback(progress, f"整理中: {current_file} ({i+1}/{total_files})")

            self._log(f"\n📄 [{i + 1}/{total_files}] 处理文件: {movie_file}")

            try:
                # 获取文件名（不含扩展名）
                file_name, file_ext = os.path.splitext(movie_file)

                # 按'.'分割，取第一部分作为文件夹名
                folder_name = file_name.split('.')[0].strip()

                if not folder_name:
                    self._log(f"⚠️ 无法从文件名提取文件夹名: {movie_file}")
                    skipped_count += 1
                    continue

                # 检查文件是否已在子文件夹中
                movie_file_path = os.path.join(folder_path, movie_file)
                if os.path.dirname(movie_file_path) != folder_path:
                    self._log(f"ℹ️ 文件已在子文件夹中，跳过: {movie_file}")
                    skipped_count += 1
                    continue

                # 创建目标文件夹
                target_folder = os.path.join(folder_path, folder_name)

                if os.path.exists(target_folder):
                    if os.path.isfile(target_folder):
                        self._log(f"❌ 目标路径是文件而非文件夹: {target_folder}")
                        skipped_count += 1
                        continue
                    else:
                        self._log(f"📁 文件夹已存在: {folder_name}")
                else:
                    os.makedirs(target_folder)
                    self._log(f"📁 创建文件夹: {folder_name}")

                # 移动文件
                target_file_path = os.path.join(target_folder, movie_file)

                if os.path.exists(target_file_path):
                    self._log(f"⚠️ 目标文件已存在，跳过移动: {target_file_path}")
                    skipped_count += 1
                else:
                    shutil.move(movie_file_path, target_file_path)
                    self._log(f"✅ 文件已移动: {movie_file} -> {folder_name}/")
                    organized_count += 1

            except Exception as error:
                self._log(f"❌ 处理文件 {movie_file} 时出错: {error}")
                skipped_count += 1

        # 阶段4：完成处理 (95-100%)
        if progress_callback:
            progress_callback(95, "正在完成整理...")

        self._log(f"\n🎉 文件整理完成!")
        self._log(f"   - 成功整理: {organized_count} 个文件")
        self._log(f"   - 跳过: {skipped_count} 个文件")

        return organized_count, skipped_count

    def generate_nfo_files_workflow(self, folder_path, options, progress_callback=None):
        """NFO文件生成的主要业务逻辑"""
        try:
            # 验证文件夹路径
            valid, error_msg = ValidationUtils.validate_folder_path(folder_path)
            if not valid:
                raise ValueError(error_msg)

            # 检查电影列表文件是否存在
            list_file_path = os.path.join(folder_path, LIST_FILE_NAME)
            if not os.path.exists(list_file_path):
                raise FileNotFoundError(f"未找到 {LIST_FILE_NAME} 文件，请先执行步骤2")

            self._log(f"📄 开始生成NFO文件: {folder_path}")

            # 阶段1：初始化 (0-10%)
            if progress_callback:
                progress_callback(0, "正在初始化...")

            # 调用现有的MovieProcessor方法
            success_count, failed_count, skipped_count = self.movie_processor.generate_nfo_files(
                folder_path, options, progress_callback=progress_callback
            )

            self._log("🎉 NFO文件生成完成!")
            return success_count, failed_count, skipped_count

        except Exception as e:
            self._log(f"❌ 生成NFO文件过程出错: {e}")
            raise
